package utils

import (
	`fmt`
	`strconv`
	`strings`
	`time`
	`unsafe`
)

func UnsafeBytes2String(b []byte) *string {
	return (*string)(unsafe.Pointer(&b))
}

func ToKB(m string) (int, error) {
	m = strings.ToUpper(myTrim(m))
	if len(m) < 3 {
		return 0, fmt.Errorf("string too short, at least len(m) == 3, but get %s\n", m)
	}

	handler := func(m string, n int) (int, error) {
		base, err := strconv.ParseFloat(m[:len(m)-2], 3)
		if err != nil {
			return 0, err
		}

		return int(float64(n) * base), nil
	}

	switch {
	case strings.HasSuffix(m, "KB"):
		return handler(m, 1)
	case strings.HasSuffix(m, "MB"):
		return handler(m, 1024)
	case strings.HasSuffix(m, "GB"):
		return handler(m, 1024*1024)
	default:
		return 0, fmt.Errorf("\"want get XXX.XXXKB or XXX.XXXMB or XXX.XXXGB(ignore case), but get %s\n", m)
	}
}

func ToMS(t string) (int64, error) {
	// like 0m0.077s
	t = myTrim(t)
	d, err := time.ParseDuration(t)
	if err != nil {
		return 0, err
	}
	return d.Milliseconds(), nil
}

func myTrim(t string) string {
	trimFunc := func(r rune) bool {
		switch r {
		case '\r':
			return true
		case '\n':
			return true
		case '\t':
			return true
		case ' ':
			return true
		default:
			return false
		}
	}
	t = strings.TrimFunc(t, trimFunc)
	return t
}
